package com.mitdy.sg.data.crawler;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.RemoteWebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.mitdy.sg.data.entity.BasketballGameEvent;
import com.mitdy.sg.data.service.BasketballGameEventService;
import com.mitdy.sg.data.service.BasketballGameQuarterScoreService;
import com.mitdy.sg.data.service.GameService;
import com.mitdy.sg.data.service.TeamService;
import com.mitdy.sg.data.vo.BasketballGameEventVO;
import com.mitdy.sg.data.vo.GameVO;
import com.mitdy.sg.data.vo.TeamVO;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.utils.UrlUtils;

@Component
public class BasketballPageProcessor implements PageProcessor {

    private static final Logger logger = LoggerFactory.getLogger(BasketballPageProcessor.class);

    private Site site;

    @Value("${system.config.gameEventUrl}")
    private String url;
    
    private int index = 0;

    @Autowired
    private BasketballGameEventService basketballGameEventService;
    
    @Autowired
    private BasketballGameQuarterScoreService basketballGameQuarterScoreService;

    @Autowired
    private GameService gameService;

    @Autowired
    private TeamService teamService;

    @Override
    public void process(Page page) {
        try {
            WebDriver driver = new ChromeDriver();
            driver.get(page.getUrl().get());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            RemoteWebElement chooseDateElement = (RemoteWebElement) driver.findElement(By.id("chooseDate"));
            logger.info("welElement: " + chooseDateElement.getClass());
            chooseDateElement.click();
            List<WebElement> dateOptions = chooseDateElement.findElements(By.xpath("//*/a[@onclick=\"ChooseDate(this)\"]"));
            logger.info("dateOptions.size()： " + dateOptions.size());
            for (WebElement webElement : dateOptions) {
                logger.info("text: " + webElement.getText());
            }
            if (CollectionUtils.isNotEmpty(dateOptions)) {
                logger.info("index: {}", index);
                dateOptions.get(index).click();
            }
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            WebElement dateElement = chooseDateElement.findElement(By.xpath("//*[@id='displayDate']"));
            String dateText = dateElement.getText();
            Date date = null;
            date = parse(dateText);
            logger.info("date: {}", date);
            
            List<WebElement> tableElements = chooseDateElement.findElements(By.xpath("//table[contains(@rel, 'bk_')]"));
            System.out.println("tableElements: " + tableElements.size());
            for (WebElement tableElement : tableElements) {

                try {
                    extractFrom(date, tableElement);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } 
        } catch (Exception e) {
//            throw new RuntimeException(e);
        }

    }

    private void extractFrom(Date date, WebElement tableElement) throws ParseException {
        WebElement captionElement = tableElement.findElement(By.xpath("./caption/a"));
        String gameName = captionElement.getText();
        System.out.println("text: " + gameName);

        logger.info("gameName: " + gameName);

        Long gameId = null;
        GameVO gameVO = gameService.getGameByName(gameName);

        if (gameVO != null) {
            logger.info("exists game: {}", gameVO.getGameName());
            gameId = gameVO.getId();
        } else {
            gameVO = new GameVO();
            gameVO.setGameType("1");
            gameVO.setGameName(StringUtils.trim(gameName));
            gameVO.setCreateUser(Thread.currentThread().getName());
            gameVO.setCreateTime(new Date());
            gameVO = gameService.addGame(gameVO);
            logger.info("add new game: {}", gameVO.getGameName());

            gameId = gameVO.getId();
        }

        List<WebElement> mainRowElements = tableElement.findElements(By.xpath("./*//tr[contains(@class, 'mainRow')]"));
        System.out.println("game count: " + mainRowElements.size());

        for (WebElement mainRowElement : mainRowElements) {
            WebElement statusElement = mainRowElement.findElement(By.xpath("./td[contains(@class, 'status')]"));
            if (!"结束".equals(statusElement.getText().trim())) {
                continue;
            }
            
            String id = mainRowElement.getAttribute("id");
            String prefix = id.substring(0, id.lastIndexOf("_"));

            WebElement team2TrElement = tableElement.findElement(By.xpath("./*//tr[contains(@id, '" + prefix + "_secondRow')]"));

            WebElement timeElement = mainRowElement.findElement(By.xpath("./td[contains(@class, 'time')]"));
            String gameTimeText = timeElement.getText();
            System.out.print(gameTimeText + " ");

            WebElement team1TdElement = mainRowElement.findElement(By.xpath("./td[contains(@class, 'teamName')]"));
            WebElement team2TdElement = team2TrElement.findElement(By.xpath("./td[contains(@class, 'teamName')]"));

            if (team1TdElement != null && team2TdElement != null) {
                Long team1Id = null, team2Id = null;
                String team1Name = team1TdElement.getText();
                TeamVO team1VO = teamService.getTeamByName(team1Name);
                String team2Name = team2TdElement.getText();
                TeamVO team2VO = teamService.getTeamByName(team2Name);
                

                if (team1VO == null) {
                    team1VO = new TeamVO();
                    team1VO.setTeamName(team1Name);
                    team1VO.setCreateUser(Thread.currentThread().getName());
                    team1VO.setCreateTime(new Date());
                    team1VO.setLastUpdateUser(Thread.currentThread().getName());
                    team1VO.setLastUpdateTime(new Date());
                    team1VO = teamService.addTeam(team1VO);
                }
                team1Id = team1VO.getId();

                logger.info("team1Id: {}", team1Id);

                if (team2VO == null) {
                    team2VO = new TeamVO();
                    team2VO.setTeamName(team2Name);
                    team2VO.setCreateUser(Thread.currentThread().getName());
                    team2VO.setCreateTime(new Date());
                    team2VO.setLastUpdateUser(Thread.currentThread().getName());
                    team2VO.setLastUpdateTime(new Date());
                    team2VO = teamService.addTeam(team2VO);
                }
                team2Id = team2VO.getId();
                logger.info("team2Id: {}", team2Id);

                System.out.println(team1Name + " VS " + team2Name);
                List<WebElement> team1ScoresElements = mainRowElement.findElements(By.xpath("./td[contains(@class, 'score')]"));
                for (WebElement team1ScoreElement : team1ScoresElements) {
                    String score = team1ScoreElement.getText();
                    System.out.print(score + " ");
                }
                System.out.print(" : ");
                List<WebElement> team2ScoresElements = team2TrElement.findElements(By.xpath("./td[contains(@class, 'score')]"));
                for (WebElement team2ScoreElement : team2ScoresElements) {
                    String score = team2ScoreElement.getText();
                    System.out.print(score + " ");
                }
                System.out.println();

                BasketballGameEvent basketballGameEventQuery = new BasketballGameEvent();
                basketballGameEventQuery.setGameId(gameId);
                basketballGameEventQuery.setGameDate(date);
                basketballGameEventQuery.setTeam1Id(team1Id);
                basketballGameEventQuery.setTeam2Id(team2Id);
                BasketballGameEventVO basketballGameEvent = basketballGameEventService.getBasketballGameEventByGameIdAndDate(basketballGameEventQuery);
                
                if (basketballGameEvent == null) {
                    basketballGameEvent = new BasketballGameEventVO();
                }
                basketballGameEvent.setGameDate(date);
                basketballGameEvent.setGameDateStart(parseTime(gameTimeText));
                basketballGameEvent.setGameType(gameVO.getGameType());
                basketballGameEvent.setGameId(gameId);
                basketballGameEvent.setGameStatus("3");
                basketballGameEvent.setTeam1Id(team1Id);
                basketballGameEvent.setTeam2Id(team2Id);
                String team1TotalScoreText = team1ScoresElements.get(5).getText();
                if (NumberUtils.isDigits(team1TotalScoreText)) {
                    
                }
                basketballGameEvent.setTeam1Score(Integer.valueOf(team1TotalScoreText));
                String team2TotalScoreText = team2ScoresElements.get(5).getText();
                basketballGameEvent.setTeam2Score(Integer.valueOf(team2TotalScoreText));
                
                basketballGameEvent.setCreateUser(Thread.currentThread().getName());
                basketballGameEvent.setCreateTime(new Date());
                basketballGameEvent.setLastUpdateUser(Thread.currentThread().getName());
                basketballGameEvent.setLastUpdateTime(new Date());
                
                if (basketballGameEvent.getId() == null) {
                    basketballGameEvent = basketballGameEventService.addBasketballGameEvent(basketballGameEvent);
                    logger.info("create GameEvent: {}", basketballGameEvent.getId());
                } else {
                    basketballGameEvent = basketballGameEventService.updateBasketballGameEvent(basketballGameEvent);
                    logger.info("update GameEvent: {}", basketballGameEvent.getId());
                }

            }

        }
    }
    
    private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy /MM / dd");
    private static SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm");
    public Date parse(String value) throws ParseException {
        value = value.substring(0, value.lastIndexOf("("));
        Calendar calendar = GregorianCalendar.getInstance();
        value = calendar.get(Calendar.YEAR) + " /" + value;
        return formatter.parse(value);

    }
    
    public Date parseTime(String value) throws ParseException {
        return timeFormatter.parse(value);

    }
    
    @Override
    public Site getSite() {
        if (site == null) {
            logger.info("ur: {}", url);
            site = Site.me().setDomain(UrlUtils.getDomain(url));
        }
        return site;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public String getUrl() {
        return url;
    }

}
